package com.resou.reader;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.media.Image;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bytedance.sdk.openadsdk.AdSlot;
import com.bytedance.sdk.openadsdk.TTAdNative;
import com.bytedance.sdk.openadsdk.TTSplashAd;
import com.qq.e.ads.splash.SplashAD;
import com.qq.e.ads.splash.SplashADListener;
import com.qq.e.comm.util.AdError;
import com.resou.reader.MainActivity;
import com.resou.reader.R;
import com.resou.reader.ReSouApplication;
import com.resou.reader.advert.TTAdManagerHolder;
import com.resou.reader.advert.WeakHandler;
import com.resou.reader.api.ApiConstant;
import com.resou.reader.api.ApiImp;
import com.resou.reader.api.entry.Result;
import com.resou.reader.api.service.UserService;
import com.resou.reader.choosegender.ChooseGenderActivity;
import com.resou.reader.commom.Constant;
import com.resou.reader.mine.IView.UserInstance;
import com.resou.reader.utils.Constants;
import com.resou.reader.utils.PreferenceUtil;
import com.resou.reader.utils.ToastUtil;
import com.umeng.analytics.MobclickAgent;
import com.umeng.message.PushAgent;

import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;

import org.jetbrains.annotations.Contract;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class SplashActivity extends AppCompatActivity implements WeakHandler.IHandler, SplashADListener {
    private TTAdNative mTTAdNative;
    private FrameLayout mSplashContainer;
    //是否强制跳转到主页面
    private boolean mForceGoMain;

    //开屏广告加载发生超时但是SDK没有及时回调结果的时候，做的一层保护。
    private final WeakHandler mHandler = new WeakHandler(this);
    //开屏广告加载超时时间,建议大于1000,这里为了冷启动第一次加载到广告并且展示,示例设置了2000ms
    private static final int AD_TIME_OUT = 2000;
    private static final int MSG_GO_MAIN = 1;
    //开屏广告是否已经加载
    private boolean mHasLoaded;
    private RelativeLayout rlBottom;


    //记录拉取广告的时间
    private long fetchSplashADTime = 0;
    /***
     * 腾讯广告
     */
    private SplashAD splashAD;
    public boolean canJump = false;
    private static final String SKIP_TEXT = "点击跳过 %d";
    /**
     * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
     * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
     * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值（单位ms）
     **/
    private Handler handler = new Handler(Looper.getMainLooper());
    ImageView ivSplash;
    Random random = new Random();
    boolean isCSJ = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_splash);
        rlBottom = findViewById(R.id.rlBottom);
        ivSplash = findViewById(R.id.ivSplash);

        initSplash();
    }

    private void goChooseGenderActivity() {
        ChooseGenderActivity.start(this);
        finish();
    }

    /**
     * 是否已选择性别
     *
     * @return
     */
    private boolean isChosenGender() {
        return PreferenceUtil.getInstance(this).loadUserGender() != 0;
    }

    private void toNext() {
        //判断是否已选择男女
        if (isChosenGender()) {
            rlBottom.setVisibility(View.VISIBLE);
            if (isCSJ) {
                loadSplashAd();
            } else {
                fetchSplashAD(this, mSplashContainer, Constants.APPID, Constants.POS_ID, this, AD_TIME_OUT);
            }
        } else {
            goChooseGenderActivity();
        }
    }

    /**
     * 穿山甲加载开屏广告
     */
    private void loadSplashAd() {

        //step3:创建开屏广告请求参数AdSlot,具体参数含义参考文档
        AdSlot adSlot = new AdSlot.Builder()
                .setCodeId("812753336")
                .setSupportDeepLink(true)
                .setImageAcceptedSize(1080, 1920)
                .build();
        //step4:请求广告，调用开屏广告异步请求接口，对请求回调的广告作渲染处理
        mTTAdNative.loadSplashAd(adSlot, new TTAdNative.SplashAdListener() {
            @Override
            @MainThread
            public void onError(int code, String message) {
                Log.d(TAG, message);
                mHasLoaded = true;
//                ToastUtil.makeShortToast(message);
                goHome();
            }

            @Override
            @MainThread
            public void onTimeout() {
                mHasLoaded = true;
//                ToastUtil.makeShortToast("开屏广告加载超时");
                goHome();
            }

            @Override
            @MainThread
            public void onSplashAdLoad(TTSplashAd ad) {
                Log.d(TAG, "开屏广告请求成功");
                mHasLoaded = true;
                mHandler.removeCallbacksAndMessages(null);
                if (ad == null) {
                    return;
                }
                //获取SplashView
                View view = ad.getSplashView();
                mSplashContainer.removeAllViews();
                //把SplashView 添加到ViewGroup中,注意开屏广告view：width >=70%屏幕宽；height >=50%屏幕宽
                mSplashContainer.addView(view);
                //设置不开启开屏广告倒计时功能以及不显示跳过按钮,如果这么设置，您需要自定义倒计时逻辑
                //ad.setNotAllowSdkCountdown();

                //设置SplashView的交互监听器
                ad.setSplashInteractionListener(new TTSplashAd.AdInteractionListener() {
                    @Override
                    public void onAdClicked(View view, int type) {
                        Log.d(TAG, "onAdClicked");
                    }

                    @Override
                    public void onAdShow(View view, int type) {
                        Log.d(TAG, "onAdShow");
//                        view.start
                    }

                    @Override
                    public void onAdSkip() {
                        Log.d(TAG, "onAdSkip");
                        goHome();
                    }

                    @Override
                    public void onAdTimeOver() {
                        Log.d(TAG, "onAdTimeOver");
                        goHome();
                    }
                });
            }
        }, AD_TIME_OUT);
    }

    /**
     * 拉取开屏广告，开屏广告的构造方法有3种，详细说明请参考开发者文档。
     *
     * @param activity    展示广告的activity
     * @param adContainer 展示广告的大容器
     * @param appId       应用ID
     * @param posId       广告位ID
     * @param adListener  广告状态监听器
     * @param fetchDelay  拉取广告的超时时长：取值范围[3000, 5000]，设为0表示使用广点通SDK默认的超时时长。
     */
    private void fetchSplashAD(Activity activity, ViewGroup adContainer,
                               String appId, String posId, SplashADListener adListener, int fetchDelay) {
        fetchSplashADTime = System.currentTimeMillis();

        splashAD = new SplashAD(activity, adContainer, appId, posId, adListener,
                fetchDelay);
    }

    /**
     * 检测是否已拥有所有权限
     *
     * @return 拥有所有权限则返回true
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean checkAndRequestPermission() {
        //缺少的权限
        List<String> lackedPermission = new ArrayList<>();
        //全部权限
        String[] permissionList = new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_PHONE_STATE,
        };
//        String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
//                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CALL_PHONE,
//                Manifest.permission.READ_LOGS, Manifest.permission.READ_PHONE_STATE,
//                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.SET_DEBUG_APP,
//                Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.GET_ACCOUNTS,
//                Manifest.permission.WRITE_APN_SETTINGS};
//        ActivityCompat.requestPermissions(mActivity,mPermissionList,123);
        for (String permission : permissionList) {
            if (!(checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED)) {
                lackedPermission.add(permission);
            }
        }
        if (lackedPermission.size() == 0) {
            return true;
        } else {
            // 请求所缺少的权限，在onRequestPermissionsResult中再看是否获得权限，如果获得权限就可以调用SDK，否则不要调用SDK。
            String[] requestPermissions = new String[lackedPermission.size()];
            String[] strings = lackedPermission.toArray(requestPermissions);
            requestPermissions(strings, 1);
            return false;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (hasAllPermissionsGranted(grantResults)) {
                toNext();
            } else {
                toNext();
                Toast.makeText(this, "您已拒绝权限申请,某些功能可能无法正常使用", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private static final String TAG = "SplashActivity-App";

    private boolean hasAllPermissionsGranted(int[] grantResults) {
        for (int result : grantResults) {
            Log.d(TAG, "hasAllPermissionsGranted: " + result);
        }
        for (int result : grantResults) {
            if (result == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }

    @Override
    protected void onDestroy() {

        super.onDestroy();
        if (splashAD != null) {
            splashAD.getExt().clear();
        }
        handler.removeCallbacksAndMessages(null);
        mHandler.removeCallbacksAndMessages(null);
        ivSplash.setBackgroundResource(0);
        ivSplash = null;
        if (mSplashContainer != null && mSplashContainer.getChildCount() != 0) {
            mSplashContainer.removeAllViews();
        }

        mTTAdNative = null;
        mSplashContainer = null;
        rlBottom = null;
        setContentView(R.layout.activity_null);
        System.gc();
    }

    /**
     * 进入设置，设置权限
     */
    private void goSettings() {
        // 如果用户没有授权，那么应该说明意图，引导用户去设置里面授权。
        Toast.makeText(this, "应用缺少必要的权限！请点击\"权限\"，打开所需要的权限。", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
        finish();
    }

    private void goHome() {
        startActivity(new Intent(this, MainActivity.class));
        overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
        finish();
    }

    private void goHome2() {
        if (canJump) {
            goHome();
        } else {
            canJump = true;
        }
    }

    @Override
    public void handleMsg(Message msg) {
        if (msg.what == MSG_GO_MAIN) {
            if (!mHasLoaded) {
                goHome();
            }
        }
    }


    /**
     * 初始化initSplash
     */
    private void initSplash() {
        if (isChosenGender()) {
            mSplashContainer = (FrameLayout) findViewById(R.id.splash_container);
            int value = PreferenceUtil.getInstance(ReSouApplication.getRSApplication()).getAdProbability();
            isCSJ = (random.nextInt(100) + 1) <= value;
            Log.i(TAG, "initSplash: " + isCSJ);
            if (isCSJ) {
                //step2:创建TTAdNative对象
                mTTAdNative = TTAdManagerHolder.getInstance(SplashActivity.this).createAdNative(SplashActivity.this);
                //在合适的时机申请权限，如read_phone_state,防止获取不了imei时候，下载类广告没有填充的问题
                //在开屏时候申请不太合适，因为该页面倒计时结束或者请求超时会跳转，在该页面申请权限，体验不好
//             TTAdManagerHolder.getInstance(this).requestPermissionIfNecessary(this);
                //定时，AD_TIME_OUT时间到时执行，如果开屏广告没有加载则跳转到主页面
                mHandler.sendEmptyMessageDelayed(MSG_GO_MAIN, AD_TIME_OUT);
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setNavigationBarColor(Color.TRANSPARENT);
        }

        //Android M之前不需要动态获取权限，直接计时
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            toNext();
        } else {
            if (checkAndRequestPermission()) {
                toNext();
            }
        }
        PushAgent.getInstance(SplashActivity.this).onAppStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mForceGoMain) {
            mHandler.removeCallbacksAndMessages(null);
            goHome();
        }
        if (canJump) {
            handler.removeCallbacksAndMessages(null);
            goHome2();
        }
        canJump = true;
        MobclickAgent.onResume(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        mForceGoMain = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        MobclickAgent.onPause(this);
        canJump = false;
    }

    @Override
    public void onADDismissed() {
        goHome2();
    }

    @Override
    public void onNoAD(AdError adError) {
        Log.i(
                "AD_DEMO",
                String.format("LoadSplashADFail, eCode=%d, errorMsg=%s", adError.getErrorCode(),
                        adError.getErrorMsg()));
        /**
         * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
         * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
         * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值
         **/
        long alreadyDelayMills = System.currentTimeMillis() - fetchSplashADTime;//从拉广告开始到onNoAD已经消耗了多少时间
        long shouldDelayMills = alreadyDelayMills > AD_TIME_OUT ? 0 : AD_TIME_OUT
                - alreadyDelayMills;//为防止加载广告失败后立刻跳离开屏可能造成的视觉上类似于"闪退"的情况，根据设置的minSplashTimeWhenNoAD
        // 计算出还需要延时多久
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                goHome2();
            }
        }, shouldDelayMills);
    }

    @Override
    public void onADPresent() {
        ivSplash.setVisibility(View.INVISIBLE); // 广告展示后一定要把预设的开屏图片隐藏起来
    }

    @Override
    public void onADClicked() {

    }

    @Override
    public void onADTick(long l) {

    }

    @Override
    public void onADExposure() {

    }

    /**
     * 开屏页一定要禁止用户对返回按钮的控制，否则将可能导致用户手动退出了App而广告无法正常曝光和计费
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}
